package cn.bby.tools.actions;

import cn.bby.tools.utils.AnActionEventUtils;
import cn.bby.tools.utils.ByteStringUtil;
import cn.bby.tools.utils.ClipboardUtil;
import cn.bby.tools.utils.StringImageUtil;
import cn.hutool.core.util.StrUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: StringPortalAction
 * @author: wby
 * @date: 2025/10/17 17:26
 * @version: 1.0
 */
public class StringPortalAction extends AnAction {

    private static final Logger log = LoggerFactory.getLogger(StringPortalAction.class);

    @Override
    public void actionPerformed(AnActionEvent e) {
        String selectedText = AnActionEventUtils.getSelectedText(e);
        List<BufferedImage> bufferedImages;
        try {
            bufferedImages = StrUtil.isBlank(selectedText) ? Collections.emptyList()
                    : encode(selectedText);
        } catch (Exception ex) {
            log.error("生成失败: ", ex);
            Messages.showErrorDialog(e.getProject(), "生成失败: " + ex.getMessage(), "错误");
            bufferedImages = Collections.emptyList();
        }

        // 创建一个可变大小的对话框，使用 Box 布局
        JFrame frame = new JFrame("String Image Viewer");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        // 使用 BoxLayout 实现垂直排列
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

        // 第一行：textControlPanel（文本标签和解码按钮）
        JPanel textControlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JButton decodeButton = new JButton("从粘贴板识别↓");
        JButton copyTextButton = new JButton("复制↓");
        textControlPanel.add(new JLabel("请输入文本："));
        textControlPanel.add(decodeButton);
        textControlPanel.add(copyTextButton);
        JLabel idText = new JLabel();
        textControlPanel.add(idText);
        // 第二行：文本域输入框
        JTextArea textArea = new JTextArea(10, 50);
        textArea.setText(selectedText);
        JScrollPane textScrollPane = new JScrollPane(textArea);

        // 第三行：imgControlPanel（生成按钮）
        JPanel imgControlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        imgControlPanel.add(new JLabel("请截图识别："));
        JButton genButton = new JButton("生成↓");
//        JButton copyImgButton = new JButton("复制↓");
        imgControlPanel.add(genButton);
//        imgControlPanel.add(copyImgButton);

        // 第四行：图片列表面板
        JPanel imagePanel = new JPanel();
        GridLayout gridLayout = new GridLayout(0, 5, 1, 1);
        fitImgLayout(gridLayout, bufferedImages.size());
        imagePanel.setLayout(gridLayout);
        for (BufferedImage image : bufferedImages) {
            JLabel imageLabel = new JLabel(new ImageIcon(image));
            imagePanel.add(imageLabel);
        }
        JScrollPane imageScrollPane = new JScrollPane(imagePanel);
        imageScrollPane.getVerticalScrollBar().setUnitIncrement(16);

        //给突破条件内边距
        imagePanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        // 按顺序添加组件到主面板
        mainPanel.add(textControlPanel);
        mainPanel.add(textScrollPane);
        mainPanel.add(imgControlPanel);
        mainPanel.add(imageScrollPane);

        frame.add(mainPanel);

        // 刷新按钮事件处理
        genButton.addActionListener(e1 -> {
            try {
                List<BufferedImage> bufferedImagesNew = encode(textArea.getText());
                imagePanel.removeAll();
                fitImgLayout(gridLayout, bufferedImagesNew.size());
                for (BufferedImage image : bufferedImagesNew) {
                    JLabel imageLabel = new JLabel(new ImageIcon(image));
                    imagePanel.add(imageLabel);
                }
                textArea.setRows(10);
                imagePanel.revalidate();
                imagePanel.repaint();

                frame.pack(); // 重新适配窗口大小
            } catch (Exception ex) {
                log.error("生成失败: ", ex);
                JOptionPane.showMessageDialog(frame, "生成失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        decodeButton.addActionListener(e1 -> {
            try {
                // 读取剪贴板的图片
                BufferedImage image = ClipboardUtil.getImageFromClipboard();
                if (image != null) {
                    List<StringImageUtil.DecodeResult> results = StringImageUtil.decodeMultiple(image);
                    String res = ByteStringUtil.decompressMinimize(results.stream()
                            .map(StringImageUtil.DecodeResult::text)
                            .collect(Collectors.joining()));
                    List<Integer> indexes = results.stream()
                            .map(StringImageUtil.DecodeResult::index)
                            .toList();
                    String ids = indexes.stream()
                            .map(String::valueOf)
                            .collect(Collectors.joining(","));
                    List<Integer> loss = new ArrayList<>();
                    for (int i = 1; i < indexes.size(); i++) {
                        for (int j = indexes.get(i - 1) + 1; j < indexes.get(i); j++) {
                            loss.add(j);
                        }
                    }
                    idText.setText("indexes: " + ids);
                    textArea.setText(res);
                    textArea.setRows(40);
                    if (!loss.isEmpty()) {
                        Messages.showErrorDialog(frame, "图片识别结果不连续，请检查图片是否完整，缺失的索引为：" + loss, "提示: 图片有缺失");
                    }
                } else {
                    JOptionPane.showMessageDialog(frame, "剪贴板中没有找到图片", "提示", JOptionPane.WARNING_MESSAGE);
                }
            } catch (Exception ex) {
                log.error("解码失败: ", ex);
                JOptionPane.showMessageDialog(frame, "解码失败，请调整截图尺寸: " + ex.getMessage(), "错误: 解码失败", JOptionPane.ERROR_MESSAGE);
            }
            frame.pack(); // 重新适配窗口大小
        });

        copyTextButton.addActionListener(e1 -> {
            String text = textArea.getText();
            ClipboardUtil.setTextToClipboard(text);
        });
//        copyImgButton.addActionListener(e1 -> {
//            if (bufferedImages != null) {
//                ClipboardUtil.setImageToClipboard(image);
//            }
//        });

        frame.pack();
        //让窗口居中
        frame.setLocationRelativeTo(null);
        if (StrUtil.isBlank(selectedText) || !bufferedImages.isEmpty()) {
            frame.setVisible(true);
        } else {
            //删除
            frame.dispose();
        }

    }

    private static @NotNull List<BufferedImage> encode(String text) {
        String textMin = ByteStringUtil.compressMinimize(text);
        if (textMin.length() > StringImageUtil.MAX_LENGTH_PAGE * 2) {
            int cnt = (int) Math.ceil((double) textMin.length() / StringImageUtil.MAX_LENGTH_PAGE);
            if (cnt < 10) {
                int i = Messages.showYesNoDialog("选中数据过大，建议分开选择，继续将生成多张图（%s 张）？"
                                .formatted(cnt),
                        "提示: 数据过大", null);
                if (i != Messages.YES) {
                    return Collections.emptyList();
                }
            } else {
                Messages.showInfoMessage("选中数据过大，为避免引起IDE卡顿，请分开选择", "提示: 数据过大");
                return Collections.emptyList();
            }
        }
        return StringImageUtil.encodeMultiple(textMin);
    }

    private void fitImgLayout(GridLayout gridLayout, int size) {
        //尽量设置为正方形
        if (size > 0) {
            int columns = (int) Math.ceil(Math.sqrt(size));
            if (columns > 5) {
                columns = 5;
            }
            int rows = (int) Math.ceil((double) size / columns);

            gridLayout.setRows(rows);
            gridLayout.setColumns(columns);
        } else {
            gridLayout.setRows(1);
            gridLayout.setColumns(1);
        }
    }
}
